using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing.Design;
using Telerik.Charting;
using Telerik.Charting.Styles;

namespace Telerik.WinControls.UI.Design
{
    /// <summary>
    /// This class describe action tags menu for chart control in design time.
    /// </summary>
    internal class RadChartDesignersActionList : DesignerActionList
    {
        /// <summary>
        /// Link to chart control.
        /// </summary>
        public RadChart baseControl;

        private ChartDesigner designer = null;

        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="bc">Chart control</param>
        public RadChartDesignersActionList(RadChart bc) : base(bc)
        {
            baseControl = bc;

            IDesignerHost host = (IDesignerHost) bc.Site.GetService(typeof (IDesignerHost));
            designer = (ChartDesigner) host.GetDesigner(bc);
        }

        /// <summary>
        /// Method returns property descriptor by property name.
        /// </summary>
        /// <param name="propName">Property name</param>
        /// <returns>Property descriptor</returns>
        private PropertyDescriptor GetPropertyByName(string propName)
        {
            PropertyDescriptor prop = TypeDescriptor.GetProperties(baseControl)[propName];
            if (null == prop)
            {
                throw new ArgumentException("Matching property not found.", propName);
            }
            else
            {
                return prop;
            }
        }

        /// <summary>
        /// Method returns property descriptor by property name.
        /// </summary>
        /// <param name="propName">Property name</param>
        /// <param name="obj">Type name</param>
        /// <returns>Property descriptor</returns>
        private static PropertyDescriptor GetPropertyByName(string propName, object obj)
        {
            PropertyDescriptor prop = TypeDescriptor.GetProperties(obj)[propName];
            if (null == prop)
            {
                throw new ArgumentException("Matching property not found.", propName);
            }
            else
            {
                return prop;
            }
        }

        /// <summary>
        /// Create action tags menu items collection.
        /// </summary>
        /// <returns>Action tags menu items collection</returns>
        public override DesignerActionItemCollection GetSortedActionItems()
        {
            DesignerActionItemCollection items = new DesignerActionItemCollection();

            items.Add(new DesignerActionHeaderItem("Layout"));
            items.Add(new DesignerActionPropertyItem("Width", "Width: ", "Layout", "Sets the chart width."));
            items.Add(new DesignerActionPropertyItem("Height", "Height: ", "Layout", "Sets the chart height."));

            items.Add(new DesignerActionHeaderItem("Appearance"));
            items.Add(new DesignerActionPropertyItem("Title", "Title text:", "Appearance", "Sets the chart title text."));
            items.Add(new DesignerActionPropertyItem("SeriesOrientation", "Chart series orientation:", "Appearance", "Sets the chart series orientation."));
            items.Add(new DesignerActionPropertyItem("DefaultChartType", "Default chart type:", "Appearance", "Specifies the default type of the data series."));
            items.Add(new DesignerActionPropertyItem("Skin", "Skin:", "Appearance", "Specifies the skin used."));

            items.Add(new DesignerActionHeaderItem("Data"));
            items.Add(new DesignerActionPropertyItem("Series", "Chart series collection:", "Data", "Sets the chart series."));
            items.Add(new DesignerActionPropertyItem("DataSource", "Choose data source:", "Data", "Sets the data source for the chart."));

            items.Add(new DesignerActionMethodItem(this, "GetChartWizardForm", "Chart Wizard", "Setting", "View Chart Wizard", true));
            return items;
        }

        #region Action Tags Item

        /// <summary>
        /// Chart width
        /// </summary>
        public int Width
        {
            get
            {
                return baseControl.Width;
            }
            set
            {
                GetPropertyByName("Width", baseControl).SetValue(baseControl, value);
                designer.Update();
            }
        }

        /// <summary>
        /// Chart height
        /// </summary>
        public int Height
        {
            get
            {
                return baseControl.Height;
            }
            set
            {
                GetPropertyByName("Height", baseControl).SetValue(baseControl, value);
                designer.Update();
            }
        }

        /// <summary>
        /// Chart title
        /// </summary>
        public string Title
        {
            get
            {
                return baseControl.ChartTitle.TextBlock.Text;
            }
            set
            {
                GetPropertyByName("Text", baseControl.ChartTitle.TextBlock).SetValue(baseControl.ChartTitle.TextBlock, value);
                designer.Update();
            }
        }

        /// <summary>
        /// Chart image format action tags item.
        /// </summary>
        public ChartSeriesType DefaultChartType
        {
            get
            {
                return baseControl.DefaultType;
            }
            set
            {
                GetPropertyByName("DefaultType").SetValue(baseControl, value);
                designer.Update();
            }
        }

        /// <summary>
        /// Chart text quality action tags item.
        /// </summary>
        public TextQuality TextQuality
        {
            get
            {
                return baseControl.TextQuality;
            }
            set
            {
                GetPropertyByName("TextQuality").SetValue(baseControl, value);
                designer.Update();
            }
        }

        /// <summary>
        /// Chart series color palette action tags item.
        /// </summary>
        [Editor(typeof(ChartSkinEditor), typeof(UITypeEditor))]
        public string Skin
        {
            get
            {
                return this.baseControl.Skin;
            }
            set
            {
                this.GetPropertyByName("Skin").SetValue(this.baseControl, value);
                designer.Update();
            }
        }

        /// <summary>
        /// Chart series action tags item.
        /// </summary>
        [Editor(typeof (SeriesCollectionEditorFromAL), typeof (UITypeEditor))]
        public ChartSeriesCollection Series
        {
            get
            {
                return baseControl.Series;
            }
        }

        /// <summary>
        /// Chart series orientation action tags item.
        /// </summary>
        public ChartSeriesOrientation SeriesOrientation
        {
            get
            {
                return baseControl.SeriesOrientation;
            }
            set
            {
                GetPropertyByName("SeriesOrientation").SetValue(baseControl, value);
                designer.Update();
            }
        }

        /// <summary>
        /// Chart data source picker action tags item.
        /// </summary>
        [DefaultValue(""), AttributeProvider(typeof (IListSource)), RefreshProperties(RefreshProperties.Repaint)]
        public object DataSource
        {
            get
            {
                return baseControl.DataSource;
            }
            set
            {
                try
                {
                    GetPropertyByName("DataSource").SetValue(baseControl, value);
                }
                catch
                {
                    DataSource = baseControl.DataSource;
                }
                designer.Update();
            }
        }

        /// <summary>
        /// Call chart wizard action tags item.
        /// </summary>
        public void GetChartWizardForm()
        {
            RadChartComponentEditor wf = new RadChartComponentEditor();
            wf.EditComponent(this.baseControl);
        }

        #endregion
    }
}